﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraBars;
using ProgramMain.Database;
using ProgramMain.Framework;
using ProgramMain.Google;

namespace ProgramMain.OpticNet
{
    public delegate SimpleOpticNetDB.VertexesRow DFindVertex(int vertexID);
    public partial class CableTunnelList : ProgramMain.Framework.BaseGridListCtl
    {
        public Coordinate nearCoordinate = null;
        public int coordinateTolerance;

        private bool m_AutoCreateDataset = true;
        public bool AutoCreateDataset
        {
            get { return m_AutoCreateDataset; }
            set { m_AutoCreateDataset = value; }
        }

        public bool AutoCloseDetail { get; set; }

        protected Database.SimpleOpticNetDB m_simpleOpticNetDB = null;

        public Database.SimpleOpticNetDB SimpleOpticNetDB
        {
            get { return m_simpleOpticNetDB; }
            set
            {
                m_simpleOpticNetDB = value;
                this.dataSource.DataMember = "CableTunnels";
                this.dataSource.DataSource = this.m_simpleOpticNetDB;
            }
        }

        public int CableTunnelCount
        { get { return dataSource.Count; } }

        public CableTunnelList()
        {
            InitializeComponent();

            biDetails.Caption = "Показать на карте";
        }

        public DFindVertex FindVertex = null;

        public class AcceptChangesArgs : EventArgs
        {
            private SimpleOpticNetDB.CableTunnelsDataTable _dataTable;
            public SimpleOpticNetDB.CableTunnelsDataTable DataTable
            {
                get
                {
                    return _dataTable;
                }
            }

            public AcceptChangesArgs(SimpleOpticNetDB.CableTunnelsDataTable pDataTable)
            {
                _dataTable = pDataTable;
            }
        }

        public List<int> GetCableTunnelsID(bool isNewOnly)
        {
           List<int> res = new List<int>(from q in this.m_simpleOpticNetDB.CableTunnels where (isNewOnly && q.ID < 0) || !isNewOnly select q.ID);
            return res;
        }
        public event EventHandler<AcceptChangesArgs> OnAcceptChanges;

        private int _findCableTunnel(int vertex1ID, int vertex2ID)
        {
            this.cableTunnelsTableAdapter.ClearBeforeFill = false;
            dataSource.MoveLast();
            return this.cableTunnelsTableAdapter.Fill(this.m_simpleOpticNetDB.CableTunnels, null, vertex1ID, vertex2ID, null, null, null, null, null, null);
        }

        protected override void LoadData()
        {
            if (AutoCreateDataset && m_simpleOpticNetDB == null)
            {
                SimpleOpticNetDB = new SimpleOpticNetDB();
            }
            //прочитать данные из базы и заполнить датасет
            this.cableTunnelsTableAdapter.SelectCommandTimeout = ProgramMain.Properties.Settings.Default.LongQueryTimeout;
            if (nearCoordinate == null)
            {
                this.cableTunnelsTableAdapter.Fill(this.m_simpleOpticNetDB.CableTunnels, null, null, null, null, null, null, null, null, null);
            }
            else
            {
                this.cableTunnelsTableAdapter.Fill(this.m_simpleOpticNetDB.CableTunnels, null, null, null, Convert.ToDecimal(nearCoordinate.Longitude), Convert.ToDecimal(nearCoordinate.Latitude), coordinateTolerance, null, null, null);
            }
            UpdateStatusText(this.m_simpleOpticNetDB.CableTunnels);
        }

        protected override void UpdateData()
        {
            SimpleOpticNetDB.CableTunnelsRow row = (SimpleOpticNetDB.CableTunnelsRow)((DataRowView)dataSource.Current).Row;

            //внести изменения в базу
            this.cableTunnelsTableAdapter.SetUpdateTimeout = ProgramMain.Properties.Settings.Default.LongQueryTimeout;
            this.cableTunnelsTableAdapter.Update(this.m_simpleOpticNetDB.CableTunnels);
            UpdateStatusText(this.m_simpleOpticNetDB.CableTunnels);
            m_DataSourceChanged = false;

        }

        override protected BaseModalDetailCtl CreateDetailDialog(BaseModalDetailCtl.ShowModeTypes pShowMode)
        {
            if (EBeforeDataRow != null) EBeforeDataRow(this, new GlobalData.ListEventArgs(GetCableTunnelsID(true)));
            return new CableTunnelDetail() { AutoClose = AutoCloseDetail };
        }

        protected override void biDetails_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (dataSource.Current != null)
            {
                SimpleOpticNetDB.CableTunnelsRow row = (SimpleOpticNetDB.CableTunnelsRow)((DataRowView)dataSource.Current).Row;
                FrmOpticMap map = FrmOpticMap.ShowForm();
                CoordinateRectangle tunnelRect = new CoordinateRectangle(
                    row.Longitude1,
                    row.Latitude1,
                    row.Longitude2,
                    row.Latitude2);
                Coordinate middlePoint = tunnelRect.LineMiddlePoint();
                map.SetCenterMapObject(Convert.ToDecimal(middlePoint.Longitude), Convert.ToDecimal(middlePoint.Latitude));
                map.AddCableTunnelLighted(row.ID);
            }
        }

        private SimpleOpticNetDB.VertexesRow m_FirstRow = null;

        public void AutoAddCableTunnel(SimpleOpticNetDB.VertexesRow row)
        {
            if (dataSource != null)
            {
                if (!CheckSecurityEditAction())
                    return;

                if (dataSource.Count == 0 && m_FirstRow == null)
                {
                    m_FirstRow = row;
                    return;
                }

                if (m_FirstRow.ID == row.ID) return;
                if (_findCableTunnel(m_FirstRow.ID, row.ID) > 0)
                {
                    m_FirstRow = row;
                    return;
                }

                if (dataSource.Count == 0)
                {

                    this.dataSource.AddNew();
                    SimpleOpticNetDB.CableTunnelsRow CurrentRow =
                        (SimpleOpticNetDB.CableTunnelsRow)((DataRowView)this.dataSource.Current).Row;
                    if (CurrentRow != null)
                    {
                        CurrentRow.OwnerCompanyID = m_FirstRow.OwnerCompanyID;
                        CurrentRow.Vertex1ID = m_FirstRow.ID;
                        CurrentRow.Vertex2ID = row.ID;
                        CurrentRow.Longitude1 = m_FirstRow.Longitude;
                        CurrentRow.Latitude1 = m_FirstRow.Latitude;
                        CurrentRow.Longitude2 = row.Longitude;
                        CurrentRow.Latitude2 = row.Latitude;
                        CurrentRow.CableTunnelTypeID = 1;
                        CurrentRow.LocalAttribute = 1;
                        CurrentRow.Length = (int)(new Coordinate(CurrentRow.Longitude1, CurrentRow.Latitude1).Distance(
                            new Coordinate(CurrentRow.Longitude2, CurrentRow.Latitude2)));

                        Action_Edit(this, EventArgs.Empty);
                        dataSource.EndEdit();
                        //   m_FirstRow = null;
                    }
                }
                else
                {
                    this.dataSource.MoveLast();
                    SimpleOpticNetDB.CableTunnelsRow LastRow =
                        (SimpleOpticNetDB.CableTunnelsRow)((DataRowView)this.dataSource.Current).Row;

                    //if (LastRow.ID == row.ID) return;
                    //     if (LastRow.ID > 0 && row.ID > 0)
                    if (_findCableTunnel(LastRow.Vertex2ID, row.ID) > 0) return;
                    this.dataSource.AddNew();

                    SimpleOpticNetDB.CableTunnelsRow CurrentRow =
                        (SimpleOpticNetDB.CableTunnelsRow)((DataRowView)this.dataSource.Current).Row;
                    if (CurrentRow != null)
                    {
                        CurrentRow.UserID = ProgramMain.Framework.BaseSecurity.UserID;
                        CurrentRow.OwnerCompanyID = LastRow.OwnerCompanyID;
                        if (!LastRow.IsCaptionNull())
                            CurrentRow.Caption = LastRow.Caption;
                        CurrentRow.Vertex1ID = LastRow.Vertex2ID;
                        CurrentRow.Vertex2ID = row.ID;
                        CurrentRow.Longitude1 = LastRow.Longitude2;
                        CurrentRow.Latitude1 = LastRow.Latitude2;
                        CurrentRow.Longitude2 = row.Longitude;
                        CurrentRow.Latitude2 = row.Latitude;
                        CurrentRow.LocalAttribute = 1;
                        CurrentRow.CableTunnelTypeID = 1;
                        CurrentRow.Length = (int)(new Coordinate(CurrentRow.Longitude1, CurrentRow.Latitude1).Distance(
                            new Coordinate(CurrentRow.Longitude2, CurrentRow.Latitude2)));

                        dataSource.EndEdit();

                        if (AutoAcceptChanges)
                        {
                            DBWrite();

                            if (RefreshAfterChange)
                                RefreshControl();
                        }
                        else
                            m_DataSourceChanged = true;
                    }
                }
                if (OnAcceptChanges != null)
                    OnAcceptChanges(this, new AcceptChangesArgs(this.m_simpleOpticNetDB.CableTunnels));
            }
        }

        protected override void Action_Delete(object sender, EventArgs e)
        {
            if (!AutoCreateDataset)
            {
                if (dataSource.Count > 0)
                {
                    SimpleOpticNetDB.CableTunnelsRow _tmp_DeleteCableTunnels =
                        (SimpleOpticNetDB.CableTunnelsRow)((DataRowView)dataSource.Current).Row;

                }
            }
            base.Action_Delete(sender, e);
            if (OnAcceptChanges != null)
                OnAcceptChanges(this, new AcceptChangesArgs(this.m_simpleOpticNetDB.CableTunnels));
        }

        public void AcceptChanges()
        {
            if (dataSource != null)
            {
                if (!CheckSecurityEditAction())
                    return;

                DBWrite();

                m_DataSourceChanged = false;

                if (RefreshAfterChange)
                    RefreshControl();

                if (OnAcceptChanges != null)
                    OnAcceptChanges(this, new AcceptChangesArgs(this.m_simpleOpticNetDB.CableTunnels));
            }
        }

        public void AfterNewVertex(object sebder, EventUpdateRow e)
        {
            int v2 = this.dataSource.Find("Vertex2ID", e.DataSoutceId);
            if (v2 > -1)
            {
                dataSource.Position = v2;
                SimpleOpticNetDB.CableTunnelsRow row = (SimpleOpticNetDB.CableTunnelsRow)((DataRowView)dataSource.Current).Row;
                if (row != null) row.Vertex2ID = e.DataBaseId.Value;
            }

            int v1 = this.dataSource.Find("Vertex1ID", e.DataSoutceId);
            if (v1 > -1)
            {
                dataSource.Position = v1;
                SimpleOpticNetDB.CableTunnelsRow row = (SimpleOpticNetDB.CableTunnelsRow)((DataRowView)dataSource.Current).Row;
                if (row != null) row.Vertex1ID = e.DataBaseId.Value;
            }
        }

        public void DeleteVertex(object sebder, EventUpdateRow e)
        {
            Database.SimpleOpticNetDB.VertexesRow vertexesRow1 = null;
            Database.SimpleOpticNetDB.VertexesRow vertexesRow2 = null;
            SimpleOpticNetDB.CableTunnelsRow row1 = null;
            SimpleOpticNetDB.CableTunnelsRow row2 = null;
            if (FindVertex == null) return;

            int v1 = this.dataSource.Find("Vertex1ID", e.DataSoutceId);
            if (v1 > -1)
            {
                dataSource.Position = v1;
                row1 = (SimpleOpticNetDB.CableTunnelsRow)((DataRowView)dataSource.Current).Row;
                if (row1 != null) vertexesRow2 = FindVertex(row1.Vertex2ID);
                //  this.dataSource.Remove
            }

            int v2 = this.dataSource.Find("Vertex2ID", e.DataSoutceId);
            if (v2 > -1)
            {
                dataSource.Position = v2;
                row2 = (SimpleOpticNetDB.CableTunnelsRow)((DataRowView)dataSource.Current).Row;
                if (row2 != null) vertexesRow1 = FindVertex(row2.Vertex1ID);
                //    this.dataSource.RemoveCurrent();
            }

            if (vertexesRow1 != null && vertexesRow2 != null)
            {
                this.dataSource.AddNew();

                SimpleOpticNetDB.CableTunnelsRow CurrentRow =
                    (SimpleOpticNetDB.CableTunnelsRow)((DataRowView)this.dataSource.Current).Row;
                if (CurrentRow != null)
                {

                    CurrentRow.OwnerCompanyID = vertexesRow1.OwnerCompanyID;
                    CurrentRow.Vertex1ID = vertexesRow1.ID;
                    CurrentRow.Vertex2ID = vertexesRow2.ID;
                    CurrentRow.Longitude1 = vertexesRow1.Longitude;
                    CurrentRow.Latitude1 = vertexesRow1.Latitude;
                    CurrentRow.Longitude2 = vertexesRow2.Longitude;
                    CurrentRow.Latitude2 = vertexesRow2.Latitude;
                    CurrentRow.CableTunnelTypeID = 1;
                    CurrentRow.Length = (int)(new Coordinate(CurrentRow.Longitude1, CurrentRow.Latitude1).Distance(
                        new Coordinate(CurrentRow.Longitude2, CurrentRow.Latitude2)));
                    this.dataSource.EndEdit();
                }
            }

            if (row1 != null)
            {
                dataSource.Position = this.dataSource.Find("ID", row1.ID);
                this.dataSource.RemoveCurrent();
            }

            if (row2 != null)
            {
                dataSource.Position = this.dataSource.Find("ID", row2.ID);
                this.dataSource.RemoveCurrent();
            }

            if (dataSource.Count == 0)
            {
                if (vertexesRow1 != null && vertexesRow2 == null) m_FirstRow = vertexesRow1;
                if (vertexesRow1 == null && vertexesRow2 != null) m_FirstRow = vertexesRow2;
            }
            else
            {
                dataSource.MoveLast();
            }
        }

        public void SetFilter(int? vertexID)
        {
            this.dataSource.Filter = !vertexID.HasValue ? "" : string.Format("Vertex2ID={0} OR Vertex1ID={1}", vertexID, vertexID);
            if (!vertexID.HasValue) this.dataSource.MoveLast();
        }

        public List<int> GetCableTunnelsID()
        {
            List<int> res = new List<int>();
            dataSource.MoveFirst();
            int count = this.dataSource.Count;
            for (int index = 0; index < count; index++)
            {
                dataSource.Position = index;
                if (dataSource.Current != null)
                    res.Add(((SimpleOpticNetDB.CableTunnelsRow)((DataRowView)dataSource.Current).Row).ID);
            }
            return res;
        }

        public void EditCoordinateNewCableTunnels(Coordinate coordinate, Coordinate oldCoordinate)
        {
            dataSource.MoveFirst();
            int count = this.dataSource.Count;
            for (int index = 0; index < count; index++)
            {
                dataSource.Position = index;
                SimpleOpticNetDB.CableTunnelsRow row = (SimpleOpticNetDB.CableTunnelsRow)((DataRowView)dataSource.Current).Row;
                if (row.Latitude1 == (decimal)oldCoordinate.Latitude && row.Longitude1 == (decimal)oldCoordinate.Longitude)
                {
                    row.Latitude1 = (decimal)coordinate.Latitude;
                    row.Longitude1 = (decimal)coordinate.Longitude;
                }

                if (row.Latitude2 == (decimal)oldCoordinate.Latitude && row.Longitude2 == (decimal)oldCoordinate.Longitude)
                {
                    row.Latitude2 = (decimal)coordinate.Latitude;
                    row.Longitude2 = (decimal)coordinate.Longitude;
                }
            }
            dataSource.EndEdit();
            if (OnAcceptChanges != null)
                OnAcceptChanges(this, new AcceptChangesArgs(this.m_simpleOpticNetDB.CableTunnels));
        }

        protected override void biAddDocument_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (dataSource.Current != null)
            {
                SimpleOpticNetDB.CableTunnelsRow row = (SimpleOpticNetDB.CableTunnelsRow)((DataRowView)dataSource.Current).Row;
                new DocumentList() { CableTunnelID = row.ID }.AddDocument();

            }
        }

        protected override void biDocumentList_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (dataSource.Current != null)
            {
                SimpleOpticNetDB.CableTunnelsRow row = (SimpleOpticNetDB.CableTunnelsRow)((DataRowView)dataSource.Current).Row;
                new FrmDocumentList() { CableTunnelID = row.ID }.ShowDialog();
            }
        }

        public SimpleOpticNetDB.CableTunnelsRow FindCableTunnel(int CableTunnelID)
        {
            int v = this.dataSource.Find("ID", CableTunnelID);
            if (v > -1)
            {
                dataSource.Position = v;
                SimpleOpticNetDB.CableTunnelsRow row = (SimpleOpticNetDB.CableTunnelsRow)((DataRowView)dataSource.Current).Row;
                return row;
            }
            else
            {
                return null;
            }
        }

        public void DeleteCableTunnel(int CableTunnelID)
        {
            if(FindCableTunnel(CableTunnelID) != null)
                biDelete.PerformClick();
        }

        public void EditNewCableTunnel(int CableTunnelID)
        {
            if (FindCableTunnel(CableTunnelID) != null)
            {
                biEdit.PerformClick();
            }
        }

        public event EventHandler<EventUpdateRow> EAfterDataRow;
        public event EventHandler<GlobalData.ListEventArgs> EBeforeDataRow;

        protected override void AfterChangeDetailDialog(BaseModalDetailCtl.ShowModeTypes pShowMode, DataRowView RowView)
        {
            base.AfterChangeDetailDialog(pShowMode, RowView);

            if (EAfterDataRow != null) EAfterDataRow(this, null);
        }
    }
}